package com.xing.java8test;

import com.google.common.collect.Maps;
import lombok.ToString;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * Author: linjx
 * Date: 2018/9/8
 */
public class FunctionTest {
    interface Condition {
        boolean match();
    }

    static final Map<Function, String> map = new HashMap<>();
    static final Map<Predicate, String> map2 = new HashMap<>();

    @ToString
    private static class Apple{
        private String name;
        public Apple(String name) {
            this.name = name;
        }
    }

    @Test
    public void testFunctionMap() {
        Function<String, Apple> function1 = (name) -> new Apple(name);
        Function<String, Apple> function2 = (name) -> new Apple(name);

        map.put(function1, "hello1");
        map.put(function2, "hello2");

        for(Function function : map.keySet()) {
            System.err.println(function.hashCode());
            System.err.println(map.get(function));

        }
    }

    static class MyException extends Exception {
        public MyException(String message) {
            super(message);
        }
    }

    Function<String, String> function1 =  a -> {
        if(StringUtils.equals(a, "1")) {
            throw new RuntimeException(new MyException("message"));
        }
        return a;
    };

    @Test
    public void testFunction() {
        function1.apply("1");
    }

    static void testR1(String s1, String s2) {
        System.err.println("111 " + s1 + "," + s2);
        try {
            testR4();
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
    }

    static void testR4() {
        throw new RuntimeException(new MyException("hahahah"));
    }

    static void testR2(String s1, String s2) {
        System.err.println("222 " + s1 + "," + s2);
    }

    static void testR3(String s1, String s2) {
        System.err.println("333 " + s1 + "," + s2);
    }

    RewardFunction<String, String> rewardFunction1 = (a1, a2) -> {
        testR1(a1, a2);
    };

    RewardFunction<String, String> rewardFunction2 = (a1, a2) -> {
        testR1(a1, a2);
    };

    RewardFunction<String, String> rewardFunction3 = (a1, a2) -> {
        testR1(a1, a2);
    };

    Map<String, RewardFunction<String, String>> functionMap = Maps.newHashMap();
    {
        functionMap.put("1", rewardFunction1);
        functionMap.put("2", rewardFunction2);
        functionMap.put("3", rewardFunction3);
    }

    @FunctionalInterface
    interface RewardFunction<T, R> {
        void doReward(T t, R r);
    }

    @Test
    public void testFunction2Map() {
        functionMap.get("1").doReward("ss1", "ss2");
    }
}
